﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using D3DSS.IRepository;
using System.Data.Entity;
using System.Linq.Expressions;
using System.Data.Entity.Validation;

namespace D3DSS.Repository
{
    /// <summary>
    /// 泛型仓储
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Repository<T> : IRepository<T> where T : class
    {
        internal DbContext Database { get; set; }
        internal DbSet<T> Tables { get; set; }

        /// <summary>
        /// 注入构造函数
        /// </summary>
        /// <param name="dbContext"></param>
        public Repository(DbContext dbContext)
        {
            Database = dbContext;
            Tables = Database.Set<T>();
        }

        /// <summary>
        /// 插入单条实体
        /// </summary>
        /// <param name="entity">实体</param>
        public T Add(T entity)
        {
            try
            {
                entity = Tables.Add(entity);
                SaveChanges();
                return entity;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        /// <summary>
        /// 获取单条实体
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public T Single(Expression<Func<T, bool>> expression)
        {
            return Tables.SingleOrDefault(expression);
        }

        /// <summary>
        /// 根据条件获取多条实体
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public List<T> Where(Expression<Func<T, bool>> expression)
        {
            return Tables.Where(expression).ToList();
        }

        /// <summary>
        /// 根据表达式判断实体是否存在
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        public bool Exist(Expression<Func<T, bool>> expression)
        {
            return Tables.SingleOrDefault(expression) != null;
        }

        /// <summary>
        /// 更新实体
        /// </summary>
        /// <param name="entity">实体</param>
        public void Update(T entity)
        {
            Tables.Attach(entity);
        }

        /// <summary>
        /// 根据表达式删除实体
        /// </summary>
        /// <param name="expression">表达式</param>
        public void Delete(Expression<Func<T, bool>> expression)
        {
            var entityList = Where(expression);
            entityList.ForEach(entity => { Tables.Remove(entity); });
        }

        /// <summary>
        /// 获取所有
        /// </summary>
        /// <returns></returns>
        public List<T> All()
        {
            return Tables.ToList();
        }

        /// <summary>
        /// 保存变更
        /// </summary>
        public void SaveChanges()
        {
            try
            {
                Database.SaveChanges();
            }
            catch (DbEntityValidationException exception)
            {
                throw exception;
            }
            catch (DbUnexpectedValidationException exception)
            {
                throw exception;
            }
        }
    }
}
